package cn.yunbamboos.media.config;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.yunbamboos.media.core.ICreateLocalMediaServer;
import cn.yunbamboos.media.core.IExistLocalMediaServer;
import cn.yunbamboos.media.exception.MediaException;
import cn.yunbamboos.media.hook.MediaHookService;
import cn.yunbamboos.media.core.MediaService;
import cn.yunbamboos.media.properties.YunbamboosMediaProperties;
import cn.yunbamboos.media.zlm.LocalZLMediaKitServer;
import cn.yunbamboos.media.zlm.client.ZLMClient;
import cn.yunbamboos.media.zlm.ZLMClientList;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import java.util.Timer;
import java.util.TimerTask;

@Configuration
@ConditionalOnProperty(prefix = "yunbamboos.media", name = "enabled", havingValue = "true", matchIfMissing = false)
@EnableConfigurationProperties({YunbamboosMediaProperties.class})
@ComponentScan({"cn.yunbamboos.media.dispatcher"})
@Order
public class YunbamboosMediaAutoConfiguration implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(YunbamboosMediaAutoConfiguration.class);

    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private YunbamboosMediaProperties yunbamboosMediaProperties;
    @Value("${server.port:80}")
    private int serverPort;

    @Bean
    public ZLMClientList createZLMClientList() {
        // 本地服务ID
        String mediaServerId = yunbamboosMediaProperties.getMediaServerId();
        if (StrUtil.isBlank(mediaServerId)) {
            throw MediaException.c("Media Server Id is empty");
        }
        ZLMClient localClient = new ZLMClient.Builder()
                .serverPort(serverPort)
                .dir(yunbamboosMediaProperties.getDir())
                .ffmpegPath(yunbamboosMediaProperties.getFfmpegPath())
                .hookPath(yunbamboosMediaProperties.getHookPath())
                .mediaServerId(mediaServerId)
                .secret(yunbamboosMediaProperties.getSecret())
                .schema("http")
                .ip(yunbamboosMediaProperties.getIp())
                .port(yunbamboosMediaProperties.getPort())
                .sslPort(yunbamboosMediaProperties.getSslPort())
                .rtspPort(yunbamboosMediaProperties.getRtspPort())
                .rtspSslPort(yunbamboosMediaProperties.getRtspSslPort())
                .rtmpPort(yunbamboosMediaProperties.getRtmpPort())
                .rtmpSslPort(yunbamboosMediaProperties.getRtmpSslPort())
                .rtpPort(yunbamboosMediaProperties.getRtpPort())
                .rtcPort(yunbamboosMediaProperties.getRtcPort())
                .srtPort(yunbamboosMediaProperties.getSrtPort())
                .build();
        return new ZLMClientList(mediaServerId, localClient);
    }

    @Bean
    public MediaService createMediaService(ZLMClientList zlmClientList) {
        return new MediaService(applicationContext, zlmClientList);
    }

    @Bean
    public MediaHookService createMediaHookService(ZLMClientList zlmClientList, MediaService mediaService) {
        return new MediaHookService(zlmClientList, mediaService);
    }

    /**
     * 创建本地 ZLMediaKitServer 服务
     */
    @Bean
    public LocalZLMediaKitServer createLocalZLMediaKitServer(ZLMClientList clientList) {
        return new LocalZLMediaKitServer(clientList.getLocalZLMClient());
    }

    @Override
    public void run(String... args) throws Exception {
        // 延迟 启动本地ZLMediaKit服务
        logger.info("启动本地ZLMediaKit服务");
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                // 本地服务ID
                String mediaServerId = yunbamboosMediaProperties.getMediaServerId();
                // 查询本地服务是否存在
                IExistLocalMediaServer existLocalMediaServer = applicationContext.getBean(IExistLocalMediaServer.class);
                ICreateLocalMediaServer createLocalMediaServer = applicationContext.getBean(ICreateLocalMediaServer.class);
                if(ObjUtil.isNotNull(existLocalMediaServer) && ObjUtil.isNotNull(createLocalMediaServer)) {
                    if(!existLocalMediaServer.exist(mediaServerId)){
                        createLocalMediaServer.create(mediaServerId, "本地流媒体服务", yunbamboosMediaProperties.getIp(), yunbamboosMediaProperties.getPort(), yunbamboosMediaProperties.getSecret());
                    } 
                }
                logger.info("启动本地ZLMediaKit服务");
                LocalZLMediaKitServer server = applicationContext.getBean(LocalZLMediaKitServer.class);
                if (ObjUtil.isNotNull(server)) {
                    server.start();
                }
            }
        }, 3000);
    }

}
